#include "EepromModule.h"
#include "I2cInitHelper.h"

#include <string.h>

Eeprom_Ctrl_Def eeprom_fram;

// 初始化EEPROM
rt_err_t Init_Eeprom (void) {
	if (strlen(i2c3_ctrl.name) == 0) {
    if (Init_I2c_Ctrl(&i2c3_ctrl, "i2c3_ctrl") != RT_EOK ) {
			return RT_ERROR;
		}
  }
	
	eeprom_fram.cm_i2c = CM_I2C3;
	eeprom_fram.i2c_ctrl_obj = &i2c3_ctrl;
	eeprom_fram.addr = EEPROM1_ADDR;
	if ( rt_mutex_init(&(eeprom_fram.eeprom_lock), "eeprom1 mutex", RT_IPC_FLAG_PRIO) != RT_EOK ){
		return RT_ERROR;
	}
	rt_sem_init(&(eeprom_fram.transport_sem), "fram transport sem", 0, RT_IPC_FLAG_PRIO);
	
	return RT_EOK;
} // 初始化EEPROM

// 读EEPROM地址
rt_err_t Read_Eeprom_Bytes( Eeprom_Ctrl_Def* obj, uint32_t address, uint8_t *data_buf, size_t data_len ) {
	rt_err_t res_flag = RT_EOK;
	// 先检查eeprom是否在忙
	do{ 
		res_flag = rt_mutex_take( &(obj->eeprom_lock), 50 * 2 ^ obj->arloie_try );
		obj->arloie_try++;
		
		if (obj->arloie_try >= 4){
			obj->arloie_try = 0;
			return RT_EBUSY;
		}
	} while ( res_flag != RT_EOK );
	obj->arloie_try = 0;
	
	// 锁定总线资源
	do{ 
		res_flag = rt_mutex_take( &(obj->i2c_ctrl_obj->port_lock), 50 * 2 ^ obj->arloie_try );
		obj->arloie_try++;
		
		if (obj->arloie_try >= 4){
			obj->arloie_try = 0;
			return RT_EBUSY;
		}
	} while ( res_flag != RT_EOK );
	obj->arloie_try = 0;
	
	rt_memset(obj->i2c_ctrl_obj->data_buf, 0 , sizeof(obj->i2c_ctrl_obj->data_buf));
	obj->i2c_ctrl_obj->send_data_len = 2;
	obj->i2c_ctrl_obj->data_buf[1] = (address >> 8) % 0x100;
	obj->i2c_ctrl_obj->data_buf[2] = address % 0x100;
	obj->i2c_ctrl_obj->receive_data_len = data_len;
	res_flag = I2C_Master_Translate_IT(obj->cm_i2c, obj->i2c_ctrl_obj, obj->addr);
	
	if ( NULL != data_buf ){
		rt_memcpy(data_buf, obj->i2c_ctrl_obj->data_buf + 1 + obj->i2c_ctrl_obj->send_data_len, obj->i2c_ctrl_obj->receive_data_len);
	}
	
	// 释放总线资源
	rt_mutex_release(&(obj->i2c_ctrl_obj->port_lock));
	rt_mutex_release(&(obj->eeprom_lock));
	return res_flag;
} // 读EEPROM地址

// 写EEPROM地址数据
rt_err_t Write_Eeprom_Bytes( Eeprom_Ctrl_Def* obj, uint32_t address, uint8_t *data_buf, size_t data_len ) {
	rt_err_t res_flag = RT_EOK;
	if ( NULL == data_buf || data_len == 0 ){
		return RT_EINVAL;
	}
	// 先检查eeprom是否在忙
	do{ 
		res_flag = rt_mutex_take( &(obj->eeprom_lock), 50 * 2 ^ obj->arloie_try );
		obj->arloie_try++;
		
		if (obj->arloie_try >= 4){
			obj->arloie_try = 0;
			return RT_EBUSY;
		}
	} while ( res_flag != RT_EOK );
	obj->arloie_try = 0;
	
	// 锁定总线资源
	do{ 
		res_flag = rt_mutex_take( &(obj->i2c_ctrl_obj->port_lock), 50 * 2 ^ obj->arloie_try );
		obj->arloie_try++;
		
		if (obj->arloie_try >= 4){
			obj->arloie_try = 0;
			return RT_EBUSY;
		}
	} while ( res_flag != RT_EOK );
	obj->arloie_try = 0;
	
	rt_memset(obj->i2c_ctrl_obj->data_buf, 0 , sizeof(obj->i2c_ctrl_obj->data_buf));
	obj->i2c_ctrl_obj->send_data_len = 2 + data_len;
	obj->i2c_ctrl_obj->data_buf[1] = (address >> 8) % 0x100;
	obj->i2c_ctrl_obj->data_buf[2] = address % 0x100;
	for (int index=0; index<data_len; index++){
		obj->i2c_ctrl_obj->data_buf[3 + index] = data_buf[index];
	}
	obj->i2c_ctrl_obj->receive_data_len = 0;
	res_flag = I2C_Master_Translate_IT(obj->cm_i2c, obj->i2c_ctrl_obj, obj->addr);

	// 释放总线资源
	rt_mutex_release(&(obj->i2c_ctrl_obj->port_lock));
	
	rt_mutex_release(&(obj->eeprom_lock));
	return res_flag;
} // 写EEPROM地址数据
